package com.jzo2o.orders.manager.handler;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.jzo2o.api.trade.RefundRecordApi;
import com.jzo2o.api.trade.dto.response.ExecutionResultResDTO;
import com.jzo2o.common.constants.UserType;
import com.jzo2o.common.utils.ArrayUtils;
import com.jzo2o.common.utils.CollUtils;
import com.jzo2o.orders.base.enums.OrderRefundStatusEnum;
import com.jzo2o.orders.base.mapper.OrdersMapper;
import com.jzo2o.orders.base.model.domain.Orders;
import com.jzo2o.orders.base.model.domain.OrdersRefund;
import com.jzo2o.orders.manager.model.dto.OrderCancelDTO;
import com.jzo2o.orders.manager.service.IOrdersManagerService;
import com.jzo2o.orders.manager.service.impl.OrdersRefundServiceImpl;
import com.jzo2o.orders.manager.strategy.OrderCancelStrategyManager;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

@Component
@Slf4j
public class OrderHandler {

    @Autowired
    private RefundRecordApi refundRecordApi;

    @Autowired
    private OrdersRefundServiceImpl ordersRefundService;

    @Autowired
    private IOrdersManagerService ordersManagerService;

    @Autowired
    private OrderHandler owner;

    @Autowired
    private OrderCancelStrategyManager orderCancelStrategyManager;

    @Autowired
    private OrdersMapper ordersMapper;

    @XxlJob(value = "handleRefundOrders")
    public void handleRefundOrders() {
        //1.定时读取退款表中的数据
        List<OrdersRefund> list = ordersRefundService.queryRefundOrderListByCount(100);//参数是一次读取的条数
        if (ArrayUtils.isEmpty(list)) {
            return;
        }
        //2.遍历退款表数据
        for (OrdersRefund ordersRefund : list) {

            //3.调用退款接口
            ExecutionResultResDTO executionResultResDTO =
                    refundRecordApi.refundTrading(ordersRefund.getTradingOrderNo(), ordersRefund.getRealPayAmount());

            //4.更新订单表中有关退款的字段
            if (executionResultResDTO != null) {
                //根据这个返回接口中的这个退款状态，更新订单表中有关退款的字段
                if (executionResultResDTO.getRefundStatus().equals(OrderRefundStatusEnum.REFUNDING.getStatus())) {
                    continue;
                }

                owner.afterRefund(ordersRefund, executionResultResDTO);//防止事务失效

            }

        }

    }


    @Transactional
    public void afterRefund(OrdersRefund ordersRefund, ExecutionResultResDTO executionResultResDTO) {
        //1) 更新订单表中退款相关字段(refund_status 退款状态 refund_no 支付服务退款单号 refund_id 第三方支付的退款单号)
        Orders orders = new Orders();
        orders.setId(ordersRefund.getId());//订单id
        orders.setRefundId(executionResultResDTO.getRefundId());
        orders.setRefundNo(executionResultResDTO.getRefundNo());
        orders.setRefundStatus(executionResultResDTO.getRefundStatus());
        boolean flag = ordersManagerService.updateById(orders);

        //删除退款表数据
        if (flag) {
            ordersRefundService.removeById(ordersRefund);
        }

    }


    /**
     * 取消超时订单
     */
    @XxlJob("cancelOverTimePayOrder")
    public void cancelOverTimePayOrder() {

        //1.查询超时未支付的订单
        //select * from orders where orders_status = 0 and pay_status=2 and create_time < now() - 15;
        List<Orders> orders = ordersMapper.selectList(Wrappers.<Orders>lambdaQuery()
                .eq(Orders::getOrdersStatus, 0)
                .eq(Orders::getPayStatus, 2)
                .lt(Orders::getCreateTime, LocalDateTime.now().minusMinutes(15))
                .last("limit 100"));
        if(CollUtils.isEmpty(orders))
        {
            return;
        }

        for (Orders order : orders) {
            //1.给策略任务所需的对象赋值
            OrderCancelDTO orderCancelDTO = new OrderCancelDTO();
            orderCancelDTO.setId(order.getId());//订单id
            orderCancelDTO.setUserId(0L);//用户id
            orderCancelDTO.setCurrentUserName("定时任务");//当前用户名称
            orderCancelDTO.setCurrentUserType(UserType.SYSTEM);//当前用户类型
            orderCancelDTO.setCancelReason("超时未支付");//取消原因
            orderCancelStrategyManager.cancel(orderCancelDTO);//调用策略
        }

    }
}
